package org.summerframework.component.security.security.service.impl;

import org.summerframework.component.security.AdminSave;
import org.summerframework.component.security.role.service.dto.UserRoleRelDTO;
import org.summerframework.component.security.security.service.DefaultRoleService;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;

import javax.annotation.Resource;
import java.util.*;

import static org.summerframework.component.security.core.interceptor.SecurityInterceptor.ADMIN;

/**
 * @author 石超
 * @version v1.0.0
 */
public class DefaultRoleServiceImpl extends AbstractRoleServiceImpl implements DefaultRoleService {
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private AdminSave adminSave;

    @Override
    public Map<String, List> get(String userId) {
        Map<String, List> map = new HashMap<>(16);

        BoundHashOperations<String, String, List> boundHashOperations = redisTemplate.boundHashOps(getResdisKey(userId));
        keys().forEach(keys -> map.put(keys, boundHashOperations.get(keys)));

        return map;
    }

    @Override
    public <T> List<T> get(String userId, String key) {
        BoundHashOperations<String, String, List<T>> boundHashOperations = redisTemplate.boundHashOps(getResdisKey(userId));

        List<T> ts = boundHashOperations.get(key);

        if (ts == null) {
            return Collections.emptyList();
        }
        return ts;
    }

    @Override
    public void remove(String userId) {
        redisTemplate.delete(getResdisKey(userId));
    }

    @Override
    public Boolean isAdmin(String userId) {
        return adminSave.isAdmin(Long.valueOf(userId)) || this.<UserRoleRelDTO>get(userId, ROLE_KEY).stream().anyMatch(userRoleRelDTO -> userRoleRelDTO.getRoleCode().equals(ADMIN));
    }

    @Override
    public Boolean isRole(String userId, String code) {
        return isAdmin(userId) || this.<UserRoleRelDTO>get(userId, ROLE_KEY).stream().anyMatch(userRoleRelDTO -> userRoleRelDTO.getRoleCode().equals(code));
    }

    @Override
    public Boolean isPermissions(String userId, String permissionsCode) {
        return this.isRole(userId, "ADMIN") || this.<String>get(userId, PERMISSIONS_LIST_KEY).contains(permissionsCode);
    }

    @Override
    public void clean() {
        redisTemplate.delete(keys());
    }

    @Override
    public Boolean hasKey(String userId) {
        Boolean flag = redisTemplate.hasKey(getResdisKey(userId));
        return flag == null ? false : flag;
    }

    @Override
    protected void put(String userId, String key, List list) {
        BoundHashOperations<String, String, List> boundHashOperations = redisTemplate.boundHashOps(getResdisKey(userId));
        boundHashOperations.put(key, list);
    }

    @Override
    protected void putOther(String userId) {

    }


    @Override
    public Set<String> keys() {
        Set<String> keys = redisTemplate.keys(ROLE_SAVE_KEY + "*");
        return keys == null ? Collections.emptySet() : keys;
    }
}
